
package com.bei_en.teacher.third.pay.web.alipay;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import com.bei_en.teacher.third.pay.controller.AlipayController;

public class RSA {

    public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

    /**
    * RSA签名
    * @param content 待签名数据
    * @param privateKey 商户私钥
    * @param input_charset 编码格式
    * @return 签名值
    */
    public static String sign(String content, String privateKey, String input_charset) {

	try {
	    PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
	    KeyFactory keyf = KeyFactory.getInstance("RSA");
	    PrivateKey priKey = keyf.generatePrivate(priPKCS8);

	    java.security.Signature signature = java.security.Signature
		    .getInstance(SIGN_ALGORITHMS);

	    signature.initSign(priKey);
	    signature.update(content.getBytes(input_charset));

	    byte[] signed = signature.sign();

	    return Base64.encode(signed);
	} catch (Exception e) {
	    e.printStackTrace();
	}

	return null;
    }

    /**
    * RSA验签名检查
    * @param content 待签名数据
    * @param sign 签名值
    * @param ali_public_key 支付宝公钥
    * @param input_charset 编码格式
    * @return 布尔值
    */
    public static boolean verify(String content, String sign, String ali_public_key,
	    String input_charset) {

	try {
	    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	    byte[] encodedKey = Base64.decode(ali_public_key);
	    PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

	    java.security.Signature signature = java.security.Signature
		    .getInstance(SIGN_ALGORITHMS);

	    signature.initVerify(pubKey);
	    signature.update(content.getBytes(input_charset));

	    boolean bverify = signature.verify(Base64.decode(sign));
	    return bverify;

	} catch (Exception e) {
	    e.printStackTrace();
	}

	return false;
    }

    /**
    * 解密
    * @param content 密文
    * @param private_key 商户私钥
    * @param input_charset 编码格式
    * @return 解密后的字符串
    */
    public static String decrypt(String content, String private_key, String input_charset)
	    throws Exception {

	PrivateKey prikey = getPrivateKey(private_key);

	Cipher cipher = Cipher.getInstance("RSA");
	cipher.init(Cipher.DECRYPT_MODE, prikey);

	InputStream ins = new ByteArrayInputStream(Base64.decode(content));
	ByteArrayOutputStream writer = new ByteArrayOutputStream();
	// rsa解密的字节大小最多是128，将需要解密的内容，按128位拆开解密
	byte[] buf = new byte[128];
	int bufl;

	while ((bufl = ins.read(buf))!=-1) {
	    byte[] block = null;

	    if (buf.length==bufl) {
		block = buf;
	    } else {
		block = new byte[bufl];
		for (int i = 0; i<bufl; i++) {
		    block[i] = buf[i];
		}
	    }

	    writer.write(cipher.doFinal(block));
	}

	return new String(writer.toByteArray(), input_charset);
    }

    /**
    * 得到私钥
    * @param key 密钥字符串（经过base64编码）
    * @throws Exception
    */
    public static PrivateKey getPrivateKey(String key) throws Exception {

	byte[] keyBytes;

	keyBytes = Base64.decode(key);

	PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);

	KeyFactory keyFactory = KeyFactory.getInstance("RSA");

	PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

	return privateKey;
    }

    public static void main(String[] args) throws Exception {

	String content = "body=\"订单号LC2016050600018\"&buyer_email=\"gcg0036@126.com\"&buyer_id=\"2088002285758207\"&discount=\"0.00\"&gmt_create=\"2016-05-06 10:42:05\"&is_total_fee_adjust=\"Y\"&notify_id=\"e653dfb28baf048a362919c972b7dc2hjm\"&notify_time=\"2016-05-06 10:42:05\"&notify_type=\"trade_status_sync\"&out_trade_no=\"LC2016050600018\"&payment_type=\"1\"&price=\"0.01\"&quantity=\"1\"&seller_email=\"2151088702@qq.com\"&seller_id=\"2088221388341710\"&subject=\"豪华商务套间\"&total_fee=\"0.01\"&trade_no=\"2016050621001004200289410158\"&trade_status=\"WAIT_BUYER_PAY\"&use_coupon=\"N\"";
	String sign1 = "ZiF5j0op7vZeY0DfmgZdX7BbGWOierV9UhAcDjT5tobfnEq8QuuLtX8gix2PN18git2u5dBKGTotK28O7LwrRQb9im1EkjCc8GcizP/Ic7vLU+DPK6CCc+zWOl7v7MEytFIHZ55ebZi8wNDxGqOKsF8hgPg4AgR/ZDUhBRecKpA=";

	String sign = sign(content, AlipayController.my_private_key, "utf-8");
	System.out.println(sign);
	System.out.println(sign1);
	System.out.println(verify(content, sign1, AlipayController.my_public_key, "utf-8"));
//	System.out.println(decrypt(sign, AlipayController.my_private_key, "utf-8"));
    }
}
